/**
 * DialogForm
 * ---------------------------------------
 * 
 * - Input data to create a constraint to validate.
 * 
 * @author Caio Thomas
 * @version 25-10-2013  
 */
package view;

import java.awt.BorderLayout;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import model.constraints.AbstractConstraint;
import model.constraints.XDF;
import model.constraints.XDFC.XDFC;
import model.validator.XDFCValidate;
import model.validator.XDFValidate;

public class DialogForm extends JDialog implements ActionListener {
	
	private static final long serialVersionUID = 1L;
	private ArrayList<JTextField> fields = new  ArrayList<JTextField>();
	public JTextField name = new JTextField("xdf");
	public JTextField context = new JTextField("agenda");
	public JTextField condExpression = new JTextField();
	public JTextField lf = new JTextField("contato / id");
	public JTextField typeLf = new JTextField("(v or n with commas ex.'v,n,v')");	
	public JTextField rg = new JTextField("contato");
	public JComboBox<String> typeRight = new JComboBox<String>();
	private JButton btnOK = new JButton("Ok");
    private JButton btnCancelar = new JButton("Cancelar");
    private JPanel botoes = new JPanel();
    private JLabel labelCond = new JLabel("Conditional Expression");
    //private JPanel XDFtype = new JPanel();
    private JPanel painel = new JPanel();
    private JPanel grid = new JPanel();
    public JRadioButton dependencyXDF = new JRadioButton("XML Functional Dependency");
    public JRadioButton dependencyXDFC = new JRadioButton("XML Conditional Functional Dependency");       
    private Initial initial;
    private Boolean edit = false; 
    private int positionArray = -1;
    private String[] columnNames = {"Constraint name:", "Context Path:", "Left Path:", "Type of equality Left:", "Right Path:"};
    
    //JRadioButton dependencyXDFI = new JRadioButton("XML Inclusion Functional Dependency");
	//Create a ButtonGroup object, add buttons to the group
    
	//dependencies.add(dependencyXDFI);
    
    public DialogForm(Initial i){            	
    	
    	super(i, "XML Constraints Validation", false);
    	initial = i;
    	
        ButtonGroup dependencies = new ButtonGroup();
        dependencies.add(dependencyXDF);
    	dependencies.add(dependencyXDFC);
    	dependencyXDF.setSelected(true);
    	
    	btnOK.setPreferredSize(new Dimension(100, 25));
        btnOK.addActionListener(this);
        
        btnCancelar.setPreferredSize(new Dimension(100, 25));
        btnCancelar.addActionListener(this);
        
        typeRight.addItem("Value");
        typeRight.addItem("Node");    
        
        dependencyXDFC.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent e) {
		        labelCond.setVisible(true);
		        condExpression.setVisible(true);			
			}
		});

        dependencyXDF.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent e) {
		        labelCond.setVisible(false);
		        condExpression.setVisible(false);			
			}
		});
        
        typeLf.addFocusListener(new FocusListener(){
            @Override
            public void focusGained(FocusEvent e){
            	if(typeLf.getText().equals("(v or n with commas ex.'v,n,v')"))
            		typeLf.setText("");
            }
            
			@Override
			public void focusLost(FocusEvent e) {
				if(typeLf.getText().equals(""))
					typeLf.setText("(v or n with commas ex.'v,n,v')");			
			}
        });
        
        int sizeConstraint = initial.validate.getConstraints().size() + 1;
        name.setText("Constraint"+ sizeConstraint);//set example name of contraint
        
        fields.add(name);
        fields.add(context);
        fields.add(lf);
        fields.add(typeLf);
        fields.add(rg);
        
        grid.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
        grid.setLayout(new GridLayout(9, 2, 5, 5));
        grid.add(new JLabel("XDF type:"));
        grid.add(dependencyXDF);
        grid.add(new JLabel(""));
        grid.add(dependencyXDFC);
        //grid.add(new JLabel(""));
        //grid.add(dependencyXDFI);
        
        int count = 0;        
        
        for(JTextField field: fields){
        	field.setPreferredSize(new Dimension(200, 25));
        	field.setMaximumSize(new Dimension(200, 25));
        	grid.add(new JLabel(columnNames[count++]));
        	grid.add(field);
        }     
        
        grid.add(new JLabel("Type of equality Right:"));
        grid.add(typeRight);
        labelCond.setVisible(false);
        condExpression.setVisible(false);        
        condExpression.setPreferredSize(new Dimension(200, 25));
        condExpression.setMaximumSize(new Dimension(200, 25));    	    
        grid.add(labelCond);
        grid.add(condExpression);
        
        painel.add(grid);     
        botoes.add(btnOK);
        botoes.add(btnCancelar);
        botoes.add(Box.createVerticalStrut(45));
        botoes.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0,Color.LIGHT_GRAY));
        //XDFtype.add(dependencyXDF);
        //XDFtype.add(dependencyXDFC);
      //  XDFtype.add(dependencyXDFI);
        //XDFtype.add(Box.createVerticalStrut(45));
        
        //XDFtype.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0,Color.LIGHT_GRAY));
        //this.add(XDFtype, BorderLayout.BEFORE_FIRST_LINE);
        this.add(painel, BorderLayout.CENTER);
        this.add(botoes, BorderLayout.SOUTH);
        this.setSize(550, 400);
        this.setLocation((java.awt.Toolkit.getDefaultToolkit()
                                        .getScreenSize().width / 2)
                                        - (this.getWidth() / 2), (java.awt.Toolkit
                                        .getDefaultToolkit().getScreenSize().height / 2)
                                        - (this.getHeight() / 2));
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);    	       
    }
    
    public JPanel getPanel(){
    	return painel;
    }
    
    /**
     * Used when it was edit constraint
     * @param insert text dialog
     * @param pos position in array of contraints
     */
    public void setTextDialog(AbstractConstraint ab, int pos){
    	name.setText(ab.getNameConstraint());//set example name of contraint
		context.setText(ab.getContext());
		lf.setText(ab.getLeftPath());
		typeLf.setText(ab.getLeftValue());
		rg.setText(ab.getRightPath());
		typeRight.setSelectedIndex(ab.getRightValue());
		
		positionArray = pos;//position in array to set new Abstract Constraint
		edit = true;
		
		if(ab instanceof XDFC) {
			dependencyXDFC.setSelected(true);
	        condExpression.setVisible(true);
	        condExpression.setText(((XDFC) ab).getCondicionalExpression());
	        labelCond.setVisible(true);
		} else {
			dependencyXDF.setSelected(true);
	        condExpression.setVisible(false);
	        labelCond.setVisible(false);
		}	
        
		this.setVisible(true);
    }

    /**
     * This function will clean the form, used when it was new window
     * @return void
     */
	public void clean(){
		int sizeConstraint = initial.validate.getConstraints().size() + 1;
        name.setText("Constraint"+ sizeConstraint);//set example name of contraint
		context.setText("");
		lf.setText("");
		typeLf.setText("(v or n with commas ex.'v,n,v')");
		rg.setText("");
		condExpression.setText("");		
		typeRight.setSelectedItem("Value");
		
        condExpression.setVisible(false);
		dependencyXDF.setSelected(true);
		labelCond.setVisible(false);
		
		edit = false;
	}
    
	@Override
	public void actionPerformed(ActionEvent e) {	
        Object origem = e.getSource();
        
        if(origem == btnOK){	
        	if(!name.getText().equals("") && !context.getText().equals("") && !lf.getText().equals("") && !rg.getText().equals("")
        	   && !typeLf.getText().equals("(v or n with commas ex.'v,n,v')")){
        		
				int countEquality = 0;
				int countPath = 1;
				for (int i = 0; i < typeLf.getText().length(); i++)  
		            if(typeLf.getText().charAt(i) == 'v' || typeLf.getText().charAt(i) == 'n')  
		            	countEquality++;										
				
				for (int i = 0; i < lf.getText().length(); i++)  
		            if(lf.getText().charAt(i) == '|')
		            	countPath++;			
				
				if(countEquality != countPath )
	                JOptionPane.showMessageDialog(this,"Checks the Type of equality Left.", "Attention", JOptionPane.ERROR_MESSAGE);	                
				else {
				
	        		if(dependencyXDF.isSelected()) {
	        			XDF xdf = new XDF();
						xdf.setNameConstraint(name.getText());
						try {
							xdf.setContextFsa(context.getText());					
							xdf.setSourceFsa(lf.getText());					
							xdf.setEquality(typeLf.getText(),"l");
							xdf.setTargetFsa(rg.getText());
							xdf.setRightValue(typeRight.getSelectedIndex());
							
							if(typeRight.getSelectedIndex() == 0)			
								xdf.setEquality("v","r");
							else
								xdf.setEquality("n","r");
							
							if(edit == false){ // new element
								XDFValidate val = new XDFValidate(xdf);					
								initial.validate.add(val);	
							} else {
								XDFValidate val = new XDFValidate(xdf);
								initial.validate.getConstraints().set(positionArray, val);					
							}
							initial.buttonValidate.setEnabled(true);    
							initial.statusbar.setText("Click in Validation.");
							this.dispose();
						
						} catch (Exception e1) {
							JOptionPane.showMessageDialog(this,"Error: Checks the regular expression of the path!", "Attention", JOptionPane.ERROR_MESSAGE);
						}						
																											
	                } else {
	        			XDFC xdfc = new XDFC();
						xdfc.setNameConstraint(name.getText());
						
						try {
							xdfc.setContextFsa(context.getText());
							xdfc.setSourceFsa(lf.getText());
							xdfc.setEquality(typeLf.getText(),"l");
							xdfc.setTargetFsa(rg.getText());       			
							xdfc.setRightValue(typeRight.getSelectedIndex());
							
							if(typeRight.getSelectedIndex() == 0)			
								xdfc.setEquality("v","r");
							else
								xdfc.setEquality("n","r");
							
							xdfc.setConditional(condExpression.getText());
							
							if(edit == false){ // new element
								XDFCValidate val = new XDFCValidate(xdfc);					
								initial.validate.add(val);	
							}  else {
								XDFCValidate val = new XDFCValidate(xdfc);
								initial.validate.getConstraints().set(positionArray, val);					
							} 
								//initial.validate.getConstraints().get(positionArray).setConstraint(xdfc);//update new data of constraint					
	
							initial.buttonValidate.setEnabled(true);    
							initial.statusbar.setText("Click in Validation.");
							this.dispose();
						} catch (Exception e1) {
			                JOptionPane.showMessageDialog(this,"Sintax error in the conditional expression.", "Attention", JOptionPane.ERROR_MESSAGE);                                                                        
						}
	        		}
	
	        		//display in the view automata 
	        		initial.displayAutomata();	        		        		
	        	} 
        	} else
                JOptionPane.showMessageDialog(this,"Fill in all fields.", "Attention", JOptionPane.ERROR_MESSAGE);				
        }        
        
        if (origem == btnCancelar)
            this.dispose();		
	}
}